# -*- coding: utf-8 -*-
#	Copyright 2005,2006,2007,2008 Spike^ekipS <spikeekips@gmail.com>
#
#	   This program is free software; you can redistribute it and/or modify
#	it under the terms of the GNU General Public License as published by
#	the Free Software Foundation; either version 2 of the License, or
#	(at your option) any later version.
#
#	This program is distributed in the hope that it will be useful,
#	but WITHOUT ANY WARRANTY; without even the implied warranty of
#	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#	GNU General Public License for more details.
#
#	You should have received a copy of the GNU General Public License
#	along with this program; if not, write to the Free Software
#	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

import lucene

from django.db.models import sql, ObjectDoesNotExist
from django.db.models.sql import constants
from django.db.models.sql.query import get_order_dir
from django.db import models, connection

import search as django_searcher
from search.lucene_to_django_model.models.sql.where import WhereNodeSearcher

from search.pylucene import TermQuery, Searcher, BooleanQuery, QUERY_BOOLEANS


class Query (sql.Query) :
	raw_queries = list()

	def __init__ (self, model, connection, where=WhereNodeSearcher) :
		super(Query, self).__init__(model, connection, where=WhereNodeSearcher)

	def __str__ (self) :
		(query, ordering, ) = self.as_sql()
		return "%s (%s)" % (query.toString(), ordering.toString())

	def add_raw_query (self, query) :
		self.raw_queries.append(query)

	def as_sql (self, with_limits=True, with_col_aliases=False):
		_query = self.where.as_sql(qn=self.quote_name_unless_alias)
		_ordering = self.get_ordering()

		# add model query
		if _query is None :
			_query = BooleanQuery()

		if self.raw_queries :
			for q in self.raw_queries :
				_query.add(
					q,
					QUERY_BOOLEANS.get(False),
				)

		_query.add(
			TermQuery(lucene.Term("__model__", django_searcher.get_model_name(self.model))),
			QUERY_BOOLEANS.get(False),
		)

		return (_query, _ordering, )

	def execute_sql (self, result_type=constants.MULTI) :
		(query, ordering, ) = self.as_sql()

		try :
			self.searcher = Searcher()
		except Exception, e :
			raise

		return [self.searcher.search(query, ordering, slice=slice(self.low_mark, self.high_mark)), ]

	def get_ordering (self) :
		ordering = self.order_by or self.model._meta.ordering
		if len(ordering) < 1 :
			return None
		else :
			_sorts = list()
			for i in ordering :
				_r = False
				_f = i
				if i[0].startswith("-") :
					_r = True
					_f = i[1:]

				if not _f.startswith("__") :
					_f = "sort__%s" % _f
				_sorts.append(lucene.SortField(_f, _r))

			if True not in [i.startswith("__pk__") or i.startswith("-__pk__") for i in ordering] :
				_sorts.append(lucene.SortField("__pk__", _r))

			return lucene.Sort(_sorts)

	def get_count (self) :
		(query, ordering, ) = self.as_sql()

		try :
			self.searcher = Searcher()
		except Exception, e :
			raise
		else :
			hits = self.searcher.get_hits(query, ordering, slice=slice(self.low_mark, self.high_mark))

		return hits.length()


"""
Description
-----------


ChangeLog
---------


Usage
-----


"""

__author__ =  "Spike^ekipS <spikeekips@gmail.com>"




